Conversation
2863520 to
00778dc
Compare
93a17ee to
df6e6fd
Compare
|
On my sample repo it worked for pyrefly and mypy, but not for pyright and ty. The difference is that in the following example they infer following types for the
from typing import reveal_type
class Foo:
def __init__(self):
self.x = 2
def some_mutant(self):
self.x = 'a'
def c(self) -> int:
reveal_type(self.x)
return self.xThus, pyrefly and mypy infer I can't think of a method to fix this currently, except for copying the whole class per mutant. I won't implement this for now, but likely will add this feature only for pyrefly and mypy for now. Remaining TODOs:
|
47f7dc7 to
3474f7e
Compare
3474f7e to
fbb1c60
Compare
|
I found one case where this filter can remove interesting mutations: class Foo:
def __init__(self, a: int) -> None:
self.a = amutates to: class Foo:
def __init__(self, a: int) -> None:
args = [a]# type: ignore
kwargs = {}# type: ignore
return _mutmut_trampoline(object.__getattribute__(self, 'xǁFooǁ__init____mutmut_orig'), object.__getattribute__(self, 'xǁStorageByteGroupǁ__init____mutmut_mutants'), args, kwargs, self)
def xǁFooǁ__init____mutmut_orig(self, a: int) -> None:
self.a = a
def xǁFooǁ__init____mutmut_1(self, a: int) -> None:
self.a = None # <- this is now a type error, because mypy/pyrefly already inferred 'int' on the first self.a = a definitionThis should be a valid mutation, however it is marked as a type error. I can't think of a way to fix this, except for copying the whole class per mutation (similar to the And in general, I've noticed that even if a mutation has a type error, there are cases where it would show a lack of tests. I've added these notes to the README. I think it can still be useful if there are too many survived mutants and you want to reduce the noise and/or improve performance. But it's not perfect, just a tradeoff. |

Fixes #467
What works so far:
./mutants/Big TODOs:
self.xasstr | None, if there are multiple methods withself.x = 'foo'andself.x = None) (EDIT: see Use type checking to detect invalid mutants #468 (comment))def foo(*args, **kwargs): return _trampoline..., pyright cannot use the types offooto infer types at places where we callx = foo(a). This can break typing). Also see Preserve original signature in trampoline #465I think for the class properties problem, we would need to define the mutated methods outside of the class and dynamically either add them or overwrite the original method. (EDIT: this won't work with
Selftypes,@classmethod, etc.)To keep the original types of mutated methods, using libcst to copy the signature should be fine.